﻿// test_unique_ptr.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <memory>

using namespace std;

class Ball
{
public:
	Ball() {
		cout << "Ball appeared." << endl;
	}
	~Ball() {
		cout << "Ball disappeared." << endl;
	}
	void Bounce() {
		cout << "Ball Bounce." << endl;
	}
};

void func()
{
    cout << "Now in func." << endl;
	unique_ptr<Ball> up{ make_unique<Ball>() };
	up->Bounce();
	cout << "Before quiting func." << endl;
}

void basis()
{
	auto ball = make_unique<Ball>();

	// 以下两种写法等同
	ball->Bounce();
	(*ball).Bounce();

	//获取裸指针
	unique_ptr<Ball> up{ make_unique<Ball>() };
	Ball* p = ball.get();

	//reset释放资源
	up.reset();
	//释放后指向新的资源
	up.reset(new Ball{});
	//释放内存
	up = nullptr;

	unique_ptr<int>up1 = make_unique<int>(100);
	//unique_ptr<int> up2(up1); //报错，unique_ptr不支持同时指向同一块内存
	//up2 = up1; //报错，unique_ptr不支持同时指向同一块内存

	//------basis
}

void some_func()
{
	Ball* p = new Ball;
	p->Bounce();
	delete p;
	/*
		如果p->Bounce执行过程抛出异常
		那么delete p 不会执行，资源也就不会释放
	*/
	unique_ptr<Ball> up{make_unique<Ball>()};
	up->Bounce();
	/*
	使用unique_ptr可以避免这个问题
	*/
}

int* my_alloc(int v)
{
	cout << "Allocation" << v << endl;
	return new int{ v };
}

void my_delalloc(int *p)
{
	cout << "Del allocating" << *p << endl;
	delete p;
}


int main()
{
	//cout << "Now in main." << endl;
	//func();
	//cout << "Complete func." << endl;
	//basis();
	unique_ptr<int, decltype(&my_delalloc)> cup{ my_alloc(100), my_delalloc };
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
